﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Lapkin.Models.DataModels;

namespace Lapkin.Models.Repositories
{
    public class ProductRepository
    {
        private readonly MainContext _db;
        private readonly SqlRepository _sqlRepository;
        public ProductRepository(MainContext db, SqlRepository sqlRepository)
        {
            _sqlRepository = sqlRepository;
            _db = db;
        }

        #region Product
        public Product CreateProduct(Action<Product> init)
        {
            var product = new Product
            {
                Id = Guid.NewGuid(),
            };
            init(product);
            try
            {
                _db.Products.Add(product);
                _db.SaveChanges();
                return product;
            }
            catch
            {
                return null;
            }
        }
        public bool UpdateProduct(Product product)
        {
            if (product.Id != Guid.Empty)
            {
                _db.Products.Attach(product);
                _sqlRepository.CheckChange(product);
                _db.Configuration.ValidateOnSaveEnabled = false;
                _db.SaveChanges();
                _db.Configuration.ValidateOnSaveEnabled = true;
                return true;
            }
            return false;
        }
        public bool RemoveProduct(Guid id)
        {
            var property = new Product { Id = id };
            _db.Products.Attach(property);
            _db.Products.Remove(property);
            try
            {
                _db.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public Product GetProduct(Expression<Func<Product, bool>> query)
        {
            return _db.Products.FirstOrDefault(query);
        }
        public IEnumerable<Product> GetListProduct()
        {
            return _db.Products.ToList();
        }
        #endregion

        #region ProductProperty
        public ProductProperty CreateProductProperty(Action<ProductProperty> init)
        {
            var newProperty = new ProductProperty
                {
                    Id = Guid.NewGuid(),
                };
            init(newProperty);
            try
            {
                _db.ProductProperties.Add(newProperty);
                _db.SaveChanges();
                return newProperty;
            }
            catch
            {
                return null;
            }
        }
        public bool UpdateProductProperty(ProductProperty property)
        {
            if (property.Id != Guid.Empty)
            {
                _db.ProductProperties.Attach(property);
                _sqlRepository.CheckChange(property);
                _db.Configuration.ValidateOnSaveEnabled = false;
                _db.SaveChanges();
                _db.Configuration.ValidateOnSaveEnabled = true;
                return true;
            }
            return false;
        }
        public bool RemoveProductProperty(Guid id)
        {
            var property = new ProductProperty { Id = id };
            _db.ProductProperties.Attach(property);
            _db.ProductProperties.Remove(property);
            try
            {
                _db.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public ProductProperty GetProductProperty(Expression<Func<ProductProperty, bool>> query)
        {
            return _db.ProductProperties.FirstOrDefault(query);
        }
        public IEnumerable<ProductProperty> GetListProductProperty()
        {
            return _db.ProductProperties.ToList();
        }
        #endregion

        #region ProductVariant
        public ProductVariant CreateProductVariant(Action<ProductVariant> init)
        {
            var productVariant = new ProductVariant
                {
                    Id = Guid.NewGuid(),
                };
            init(productVariant);
            try
            {
                _db.ProductVariants.Add(productVariant);
                _db.SaveChanges();
                return productVariant;
            }
            catch
            {
                return null;
            }

        }
        public bool UpdateProductVariant(ProductVariant variant)
        {
            if (variant.Id != Guid.Empty)
            {
                _db.ProductVariants.Attach(variant);
                _sqlRepository.CheckChange(variant);
                _db.Configuration.ValidateOnSaveEnabled = false;
                _db.SaveChanges();
                _db.Configuration.ValidateOnSaveEnabled = true;
                return true;
            }
            return false;
        }
        public bool RemoveProductVariant(Guid id)
        {
            var variant = new ProductVariant { Id = id };
            _db.ProductVariants.Attach(variant);
            _db.ProductVariants.Remove(variant);
            try
            {
                _db.SaveChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }
        public ProductVariant GetProductVariant(Expression<Func<ProductVariant, bool>> query)
        {
            return _db.ProductVariants.FirstOrDefault(query);
        }
        public IEnumerable<ProductVariant> GetListProductVariant()
        {
            return _db.ProductVariants.ToList();
        }
        #endregion
    }
}